package com.frkj.order.controller;

import com.frkj.order.cache.BusinessCache;
import com.frkj.order.cache.ConfigCache;
import com.frkj.order.cache.LoginOperatorCache;
import com.frkj.order.model.Business;
import com.frkj.order.model.Operator;
import com.frkj.order.model.UserOrder;
import com.frkj.order.util.ErrorCode;
import com.frkj.order.util.OrderConstant;
import com.frkj.order.util.UserOrderCleaner;
import com.frkj.order.vo.OrderResponse;
import com.frkj.order.vo.QueueCount;
import com.frkj.order.vo.Response;
import com.frkj.order.vo.WorkingOrder;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2016/6/27.
 */
public class QueueController extends Controller {

    /**
     * 预约叫号
     * user_type    用户类型
     * business_id  业务标识
     * open_id      微信用户openId，当user_type=0时，必须传递open_id参数
     */
    public void add() {
        OrderResponse orderResponse = new OrderResponse();

        if(ConfigCache.getConfig("OrderService").equals(OrderConstant.SERVICE_OFF)) {
            // 预约服务未开启，不接受预约
            orderResponse.setErrorCode(ErrorCode.SERVICE_CLOSED);
            orderResponse.setErrorMessage("Order service is closed, please try again later.");
            renderJson(orderResponse);
            return;
        }

        int userType = getParaToInt("user_type", -1);
        int businessId = getParaToInt("business_id", -1);
        String openId = getPara("open_id", "");


        if(userType == -1) {
            orderResponse.setErrorCode(ErrorCode.USER_TYPE_NULL);
            orderResponse.setErrorMessage("can't find [user_type] in request url");
            renderJson(orderResponse);
            return;
        }
        if (businessId == -1) {
            orderResponse.setErrorCode(ErrorCode.BUSINESS_ID_NULL);
            orderResponse.setErrorMessage("can't find [business_id] in request url");
            renderJson(orderResponse);
            return;
        }
        if (userType == OrderConstant.USER_TYPE_WEIXIN && openId.equals("")) {
            orderResponse.setErrorCode(ErrorCode.OPEN_ID_NULL);
            orderResponse.setErrorMessage("can't find [open_id] in request url");
            renderJson(orderResponse);
            return;
        }

        UserOrder userOrder = new UserOrder();
        userOrder.set("user_type", userType);
        userOrder.set("open_id", openId);
        Business business = BusinessCache.getBusiness(businessId);
        userOrder.set("business_id", business.getInt("id"));
        userOrder.set("business_name", business.getStr("name"));
        userOrder.set("business_tag", business.getStr("tag"));
        userOrder.set("status", OrderConstant.ORDER_STATUS_WAITING);
        userOrder.set("create_time", new Date());
        int currentNumber = UserOrder.me.nextOrderNumber(businessId);
        String orderNumber = genOrderNumber(business, currentNumber);
        userOrder.set("number", orderNumber);
        userOrder.save();

        orderResponse.setOrderNumber(orderNumber);

        QueueCount queueCount = UserOrder.me.getBeforWaitingCount(business.getInt("id"));
        orderResponse.setQueueCount(queueCount);

        renderJson(orderResponse);
    }

    /**
     * 产生预约号码字符串(格式可能变化）
     * @param business
     * @param number
     * @return
     */
    private String genOrderNumber(Business business, int number) {
        DecimalFormat df = new DecimalFormat("0000");
        String orderNumber = business.getStr("tag") + "-" + df.format(number);
        return orderNumber;
    }

    /**
     * 获取当前所有业务排队信息
     * operator_id  柜员id(非必须，不指定返回所有业务排队信息)
     */
    public void listWaitingQueue() {
        int operatorId = getParaToInt("operator_id", -1);
        List<QueueCount> queueCountList = UserOrder.me.getWaitingQueueInfoList(operatorId);
        renderJson(queueCountList);
    }

    /**
     * 获取当前所有正在处理业务信息
     */
    public void listWorkingOrders() {
        List<WorkingOrder> workingOrderList = UserOrder.me.getWorkingOrderList();
        renderJson(workingOrderList);
    }

    /**
     * 叫号（管理员使用）
     * operator_id  柜员id
     * window       柜员所在窗口
     * business_id  业务类型（非必须，不指定随机选择一个靠前业务；指定值必须符合柜员业务范围）
     */
    public void nextOrder() {
        OrderResponse orderResponse = new OrderResponse();

        int window = getParaToInt("window", -1);
        // business_id非必须
        int businessId = getParaToInt("business_id", -1);

        if (window == -1) {
            orderResponse.setErrorCode(ErrorCode.WINDOW_NULL);
            orderResponse.setErrorMessage("can't find [window] in request url");
            renderJson(orderResponse);
            return;
        }

        Operator operator = LoginOperatorCache.getOperator(window);
        if(operator == null) {
            orderResponse.setErrorCode(ErrorCode.WINDOW_NO_OPERATOR);
            orderResponse.setErrorMessage("there is no operator login for window （" + window + "）");
            renderJson(orderResponse);
            return;
        }
        int operatorId = operator.getInt("id");
        String operatorName = operator.getStr("name");

        if(businessId != -1) {
            // 使用叫号器此场景不存在了
            // 检查业务类型是否在柜员权限范围内
            List<Record> recordList = Db.find("select business_id from operator_business where operator_id=?", operatorId);
            boolean checked = false;
            for(Record record : recordList) {
                if(record.getInt("business_id") == businessId) {
                    checked = true;
                    break;
                }
            }
            if(!checked) {
                orderResponse.setErrorCode(ErrorCode.OPERATOR_BUSINESS_ERROR);
                orderResponse.setErrorMessage("business_id(" + businessId + ") is not in operator(" + operatorId + ")'s business list");
                renderJson(orderResponse);
                return;
            }
        }

        UserOrder userOrder = UserOrder.me.callOrder(operator, businessId, window);

        String orderNumber = userOrder.getStr("number");
        orderResponse.setOrderNumber(orderNumber);

        renderJson(orderResponse);
    }

    // 每日凌晨将排队表数据清除移至历史表（测试用）
    private void cleanUserOrder() {
        UserOrderCleaner.cleanData();
        Response response = new Response();
        renderJson(response);
    }

    /**
     * 跳过
     */
    public void ignoreOrder() {
        Response response = new Response();
        String number = getPara("number", "");
        if(number.equals("")) {
            response.setErrorCode(ErrorCode.NUMBER_NULL);
            response.setErrorMessage("can't find [number] in request url.");
            renderJson(response);
            return;
        }

        UserOrder.me.ignore(number);
        renderJson(response);
    }

    /**
     * 结束
     */
    public void endOrder() {
        Response response = new Response();
        String number = getPara("number", "");
        if(number.equals("")) {
            response.setErrorCode(ErrorCode.NUMBER_NULL);
            response.setErrorMessage("can't find [number] in request url.");
            renderJson(response);
            return;
        }

        UserOrder.me.end(number);
        renderJson(response);
    }

    /**
     * 获取业务信息
     */
    public void getBusiness() {
        int id = getParaToInt("business_id", -1);
        Business business = BusinessCache.getBusiness(id);
        renderJson(business);
    }

}
